This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new ab54bed Inprove PropertyBindingSupport (CAMEL-15396, CAMEL-15397) ab54bed is described below commit ab54bed173977fa8d386a330002f2119b3441a3b Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Tue Aug 11 17:20:12 2020 +0200 Inprove PropertyBindingSupport (CAMEL-15396, CAMEL-15397) This PR adds support for arrays in PropertyBindingSupport and fix issues when binding to list when properties have gaps. See tests in: - PropertyBindingSupportArrayTest - PropertyBindingSupportListTest --- .../camel/support/IntrospectionSupportTest.java | 30 ++++++ ...t.java => PropertyBindingSupportArrayTest.java} | 110 +++++++++++++++------ .../support/PropertyBindingSupportListTest.java | 51 +++++++++- .../support/PropertyBindingSupportMapTest.java | 2 +- .../apache/camel/support/IntrospectionSupport.java | 55 +++++++++-- .../camel/support/PropertyBindingSupport.java | 63 +++++++++++- .../camel/support/PropertyConfigurerHelper.java | 70 +++++++++++++ 7 files changed, 336 insertions(+), 45 deletions(-) diff --git a/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java b/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java index 07fbe38..18ae51e 100644 --- a/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/support/IntrospectionSupportTest.java @@ -564,4 +564,34 @@ public class IntrospectionSupportTest extends ContextTestSupport { assertEquals(ExampleBean.class, setters.get(0).getParameterTypes()[0]); assertEquals(String.class, setters.get(1).getParameterTypes()[0]); } + + + @Test + public void testArray() throws Exception { + MyBeanWithArray target = new MyBeanWithArray(); + IntrospectionSupport.setProperty(context.getTypeConverter(), target, "names[0]", "James"); + IntrospectionSupport.setProperty(context.getTypeConverter(), target, "names[1]", "Claus"); + assertEquals("James", target.getNames()[0]); + assertEquals("Claus", target.getNames()[1]); + + IntrospectionSupport.setProperty(context.getTypeConverter(), target, "names[0]", "JamesX"); + assertEquals("JamesX", target.getNames()[0]); + + IntrospectionSupport.setProperty(context.getTypeConverter(), target, "names[2]", "Andrea"); + assertEquals("JamesX", target.getNames()[0]); + assertEquals("Claus", target.getNames()[1]); + assertEquals("Andrea", target.getNames()[2]); + } + + public class MyBeanWithArray { + private String[] names = new String[10]; + + public String[] getNames() { + return names; + } + + public void setNames(String[] names) { + this.names = names; + } + } } diff --git a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportListTest.java b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportArrayTest.java similarity index 59% copy from core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportListTest.java copy to core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportArrayTest.java index 83a1acc..88bf95b 100644 --- a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportListTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportArrayTest.java @@ -17,7 +17,6 @@ package org.apache.camel.support; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.Properties; @@ -26,12 +25,15 @@ import org.apache.camel.ContextTestSupport; import org.apache.camel.PropertyBindingException; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.apache.camel.util.CollectionHelper.mapOf; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * Unit test for PropertyBindingSupport */ -public class PropertyBindingSupportListTest extends ContextTestSupport { +public class PropertyBindingSupportArrayTest extends ContextTestSupport { @Override protected CamelContext createCamelContext() throws Exception { @@ -55,7 +57,7 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { } @Test - public void testPropertiesList() throws Exception { + public void testPropertiesArray() throws Exception { Foo foo = new Foo(); Map<String, Object> prop = new LinkedHashMap<>(); @@ -72,15 +74,40 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { assertEquals(33, foo.getBar().getAge()); assertTrue(foo.getBar().isRider()); assertTrue(foo.getBar().isGoldCustomer()); - assertEquals(2, foo.getBar().getWorks().size()); - assertEquals(123, foo.getBar().getWorks().get(0).getId()); - assertEquals("Acme", foo.getBar().getWorks().get(0).getName()); - assertEquals(456, foo.getBar().getWorks().get(1).getId()); - assertEquals("Acme 2", foo.getBar().getWorks().get(1).getName()); + assertEquals(2, foo.getBar().getWorks().length); + assertEquals(123, foo.getBar().getWorks()[0].getId()); + assertEquals("Acme", foo.getBar().getWorks()[0].getName()); + assertEquals(456, foo.getBar().getWorks()[1].getId()); + assertEquals("Acme 2", foo.getBar().getWorks()[1].getName()); } @Test - public void testPropertiesListNested() throws Exception { + public void testPropertiesArrayWithGaps() throws Exception { + Foo foo = new Foo(); + + Map<String, Object> prop = new LinkedHashMap<>(); + prop.put("name", "James"); + prop.put("bar.age", "33"); + prop.put("bar.{{committer}}", "true"); + prop.put("bar.gold-customer", "true"); + prop.put("bar.works[5]", "#bean:company1"); + prop.put("bar.works[9]", "#bean:company2"); + + PropertyBindingSupport.build().bind(context, foo, prop); + + assertEquals("James", foo.getName()); + assertEquals(33, foo.getBar().getAge()); + assertTrue(foo.getBar().isRider()); + assertTrue(foo.getBar().isGoldCustomer()); + assertEquals(10, foo.getBar().getWorks().length); + assertEquals(123, foo.getBar().getWorks()[5].getId()); + assertEquals("Acme", foo.getBar().getWorks()[5].getName()); + assertEquals(456, foo.getBar().getWorks()[9].getId()); + assertEquals("Acme 2", foo.getBar().getWorks()[9].getName()); + } + + @Test + public void testPropertiesArrayNested() throws Exception { Foo foo = new Foo(); Map<String, Object> prop = new LinkedHashMap<>(); @@ -99,15 +126,36 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { assertEquals(33, foo.getBar().getAge()); assertTrue(foo.getBar().isRider()); assertTrue(foo.getBar().isGoldCustomer()); - assertEquals(2, foo.getBar().getWorks().size()); - assertEquals(666, foo.getBar().getWorks().get(0).getId()); - assertEquals("Acme", foo.getBar().getWorks().get(0).getName()); - assertEquals(456, foo.getBar().getWorks().get(1).getId()); - assertEquals("I changed this", foo.getBar().getWorks().get(1).getName()); + assertEquals(2, foo.getBar().getWorks().length); + assertEquals(666, foo.getBar().getWorks()[0].getId()); + assertEquals("Acme", foo.getBar().getWorks()[0].getName()); + assertEquals(456, foo.getBar().getWorks()[1].getId()); + assertEquals("I changed this", foo.getBar().getWorks()[1].getName()); } @Test - public void testPropertiesListFirst() throws Exception { + public void testPropertiesArrayNestedSimple() throws Exception { + Foo foo = new Foo(); + + PropertyBindingSupport.build().bind(context, foo, mapOf( + "bar.works[0].id", "666", + "bar.works[1].name", "I changed this" + )); + + assertEquals(666, foo.bar.works[0].getId()); + assertEquals("I changed this", foo.bar.works[1].getName()); + + PropertyBindingSupport.build().bind(context, foo, mapOf( + "bar.works[0].id", "999", + "bar.works[1].name", "I changed this again" + )); + + assertEquals(999, foo.bar.works[0].getId()); + assertEquals("I changed this again", foo.bar.works[1].getName()); + } + + @Test + public void testPropertiesArrayFirst() throws Exception { Bar bar = new Bar(); Map<String, Object> prop = new LinkedHashMap<>(); @@ -118,15 +166,15 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { PropertyBindingSupport.build().bind(context, bar, prop); - assertEquals(2, bar.getWorks().size()); - assertEquals(666, bar.getWorks().get(0).getId()); - assertEquals("Acme", bar.getWorks().get(0).getName()); - assertEquals(456, bar.getWorks().get(1).getId()); - assertEquals("I changed this", bar.getWorks().get(1).getName()); + assertEquals(2, bar.getWorks().length); + assertEquals(666, bar.getWorks()[0].getId()); + assertEquals("Acme", bar.getWorks()[0].getName()); + assertEquals(456, bar.getWorks()[1].getId()); + assertEquals("I changed this", bar.getWorks()[1].getName()); } @Test - public void testPropertiesNotList() throws Exception { + public void testPropertiesNotArray() throws Exception { Foo foo = new Foo(); Map<String, Object> prop = new LinkedHashMap<>(); @@ -140,13 +188,13 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { } catch (PropertyBindingException e) { assertEquals("bar.gold-customer[]", e.getPropertyName()); IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, e.getCause()); - assertTrue(iae.getMessage().startsWith("Cannot set property: gold-customer[] as either a Map/List because target bean is not a Map or List type")); + assertTrue(iae.getMessage().startsWith("Cannot set property: gold-customer[] as either a Map/List/array because target bean is not a Map, List or array type")); } } public static class Foo { - private String name; - private Bar bar = new Bar(); + String name; + Bar bar = new Bar(); public String getName() { return name; @@ -166,10 +214,10 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { } public static class Bar { - private int age; - private boolean rider; - private List<Company> works; // should auto-create this via the setter - private boolean goldCustomer; + int age; + boolean rider; + Company[] works; // should auto-create this via the setter + boolean goldCustomer; public int getAge() { return age; @@ -187,11 +235,11 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { this.rider = rider; } - public List<Company> getWorks() { + public Company[] getWorks() { return works; } - public void setWorks(List<Company> works) { + public void setWorks(Company[] works) { this.works = works; } diff --git a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportListTest.java b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportListTest.java index 83a1acc..11c4892 100644 --- a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportListTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportListTest.java @@ -26,7 +26,10 @@ import org.apache.camel.ContextTestSupport; import org.apache.camel.PropertyBindingException; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; +import static org.apache.camel.util.CollectionHelper.mapOf; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * Unit test for PropertyBindingSupport @@ -80,6 +83,31 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { } @Test + public void testPropertiesListWithGaps() throws Exception { + Foo foo = new Foo(); + + Map<String, Object> prop = new LinkedHashMap<>(); + prop.put("name", "James"); + prop.put("bar.age", "33"); + prop.put("bar.{{committer}}", "true"); + prop.put("bar.gold-customer", "true"); + prop.put("bar.works[5]", "#bean:company1"); + prop.put("bar.works[9]", "#bean:company2"); + + PropertyBindingSupport.build().bind(context, foo, prop); + + assertEquals("James", foo.getName()); + assertEquals(33, foo.getBar().getAge()); + assertTrue(foo.getBar().isRider()); + assertTrue(foo.getBar().isGoldCustomer()); + assertEquals(10, foo.getBar().getWorks().size()); + assertEquals(123, foo.getBar().getWorks().get(5).getId()); + assertEquals("Acme", foo.getBar().getWorks().get(5).getName()); + assertEquals(456, foo.getBar().getWorks().get(9).getId()); + assertEquals("Acme 2", foo.getBar().getWorks().get(9).getName()); + } + + @Test public void testPropertiesListNested() throws Exception { Foo foo = new Foo(); @@ -107,6 +135,25 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { } @Test + public void testPropertiesListNestedWithType() throws Exception { + Foo foo = new Foo(); + + // use CollectionHelper::mapOf to avoid insertion ordered iteration + PropertyBindingSupport.build().bind(context, foo, mapOf( + "bar.works[0]", "#class:" + Company.class.getName(), + "bar.works[0].name", "first", + "bar.works[1]", "#class:" + Company.class.getName(), + "bar.works[1].name", "second" + )); + + assertEquals(2, foo.getBar().getWorks().size()); + assertEquals(0, foo.getBar().getWorks().get(0).getId()); + assertEquals("first", foo.getBar().getWorks().get(0).getName()); + assertEquals(0, foo.getBar().getWorks().get(1).getId()); + assertEquals("second", foo.getBar().getWorks().get(1).getName()); + } + + @Test public void testPropertiesListFirst() throws Exception { Bar bar = new Bar(); @@ -140,7 +187,7 @@ public class PropertyBindingSupportListTest extends ContextTestSupport { } catch (PropertyBindingException e) { assertEquals("bar.gold-customer[]", e.getPropertyName()); IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, e.getCause()); - assertTrue(iae.getMessage().startsWith("Cannot set property: gold-customer[] as either a Map/List because target bean is not a Map or List type")); + assertTrue(iae.getMessage().startsWith("Cannot set property: gold-customer[] as either a Map/List/array because target bean is not a Map, List or array type")); } } diff --git a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportMapTest.java b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportMapTest.java index 3f18035..4b3b688 100644 --- a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportMapTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportMapTest.java @@ -139,7 +139,7 @@ public class PropertyBindingSupportMapTest extends ContextTestSupport { } catch (PropertyBindingException e) { assertEquals("bar.gold-customer[foo]", e.getPropertyName()); IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, e.getCause()); - assertTrue(iae.getMessage().startsWith("Cannot set property: gold-customer[foo] as either a Map/List because target bean is not a Map or List type")); + assertTrue(iae.getMessage().startsWith("Cannot set property: gold-customer[foo] as either a Map/List/array because target bean is not a Map, List or array type")); } } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java index 178e193..5dcefab 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java @@ -16,6 +16,7 @@ */ package org.apache.camel.support; +import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; @@ -199,7 +200,7 @@ public final class IntrospectionSupport { return false; } - + public static boolean isSetter(Method method) { return isSetter(method, false); } @@ -471,7 +472,7 @@ public final class IntrospectionSupport { } } } - + return rc; } @@ -621,6 +622,8 @@ public final class IntrospectionSupport { obj = new LinkedHashMap<>(); } else if (Collection.class.isAssignableFrom(returnType)) { obj = new ArrayList<>(); + } else if (returnType.isArray()) { + obj = Array.newInstance(returnType.getComponentType(), 0); } } else { // fallback as map type @@ -646,15 +649,53 @@ public final class IntrospectionSupport { value = CamelContextHelper.lookup(context, s); } if (isNotEmpty(lookupKey)) { - int idx = Integer.valueOf(lookupKey); - list.add(idx, value); + int idx = Integer.parseInt(lookupKey); + if (idx < list.size()) { + list.set(idx, value); + } else if (idx == list.size()) { + list.add(value); + } else { + // If the list implementation is based on an array, we + // can increase tha capacity to the required value to + // avoid potential re-allocation weh invoking List::add. + // + // Note that ArrayList is the default List impl that + // is automatically created if the property is null. + if (list instanceof ArrayList) { + ((ArrayList) list).ensureCapacity(idx + 1); + } + while (list.size() < idx) { + list.add(null); + } + list.add(idx, value); + } } else { list.add(value); } return true; + } else if (obj.getClass().isArray() && lookupKey != null) { + if (context != null && refName != null && value == null) { + String s = StringHelper.replaceAll(refName, "#", ""); + value = CamelContextHelper.lookup(context, s); + } + int idx = Integer.parseInt(lookupKey); + int size = Array.getLength(obj); + if (idx >= size) { + obj = Arrays.copyOf((Object[])obj, idx + 1); + + // replace array + boolean hit = IntrospectionSupport.setProperty(context, target, key, obj); + if (!hit) { + throw new IllegalArgumentException("Cannot set property: " + name + " as an array because target bean has no setter method for the array"); + } + } + + Array.set(obj, idx, value); + + return true; } else { // not a map or list - throw new IllegalArgumentException("Cannot set property: " + name + " as either a Map/List because target bean is not a Map or List type: " + target); + throw new IllegalArgumentException("Cannot set property: " + name + " as either a Map/List/array because target bean is not a Map, List or array type: " + target); } } @@ -799,7 +840,7 @@ public final class IntrospectionSupport { // allow build pattern as a setter as well return setProperty(context, typeConverter, target, name, value, null, true, false, false); } - + public static boolean setProperty(TypeConverter typeConverter, Object target, String name, Object value) throws Exception { // allow build pattern as a setter as well return setProperty(null, typeConverter, target, name, value, null, true, false, false); @@ -873,7 +914,7 @@ public final class IntrospectionSupport { // find the best match if possible LOG.trace("Found {} suitable setter methods for setting {}", candidates.size(), name); // prefer to use the one with the same instance if any exists - for (Method method : candidates) { + for (Method method : candidates) { if (method.getParameterTypes()[0].isInstance(value)) { LOG.trace("Method {} is the best candidate as it has parameter with same instance type", method); // retain only this method in the answer 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 650b0f4..5a8308b 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 @@ -16,10 +16,12 @@ */ package org.apache.camel.support; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -35,6 +37,7 @@ import org.apache.camel.CamelContext; import org.apache.camel.Component; import org.apache.camel.ExtendedCamelContext; import org.apache.camel.PropertyBindingException; +import org.apache.camel.spi.BeanIntrospection; import org.apache.camel.spi.GeneratedPropertyConfigurer; import org.apache.camel.spi.PropertyConfigurer; import org.apache.camel.spi.PropertyConfigurerGetter; @@ -778,17 +781,37 @@ public final class PropertyBindingSupport { // use configurer if possible Object answer = null; - GeneratedPropertyConfigurer configurer = context.adapt(ExtendedCamelContext.class).getConfigurerResolver().resolvePropertyConfigurer(target.getClass().getSimpleName(), context); + Class<?> type = null; + + GeneratedPropertyConfigurer configurer = PropertyConfigurerHelper.resolvePropertyConfigurer(context, target); if (configurer instanceof PropertyConfigurerGetter) { - answer = ((PropertyConfigurerGetter) configurer).getOptionValue(target, key, ignoreCase); + answer = ((PropertyConfigurerGetter)configurer).getOptionValue(target, key, ignoreCase); if (answer == null) { answer = defaultValue; } } if (answer == null) { + BeanIntrospection introspection = context.adapt(ExtendedCamelContext.class).getBeanIntrospection(); // fallback to reflection based - answer = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getOrElseProperty(target, key, defaultValue, ignoreCase); + answer = introspection.getOrElseProperty(target, key, defaultValue, ignoreCase); + if (answer == null) { + try { + Method method = introspection.getPropertyGetter(target.getClass(), key, ignoreCase); + if (method != null) { + type = method.getReturnType(); + } + } catch (NoSuchMethodException e) { + // ignore + } + } + } + + if (answer != null) { + type = answer.getClass(); + } else if (configurer instanceof PropertyConfigurerGetter) { + type = (Class<?>)((PropertyConfigurerGetter)configurer).getAllOptions(target).get(key); } + if (answer instanceof Map && lookupKey != null) { Map map = (Map) answer; answer = map.getOrDefault(lookupKey, defaultValue); @@ -804,6 +827,38 @@ public final class PropertyBindingSupport { answer = list.get(list.size() - 1); } } + } else if (type != null && type.isArray() && lookupKey != null) { + int idx = Integer.parseInt(lookupKey); + int size = answer != null ? Array.getLength(answer) : 0; + if (idx >= size) { + answer = answer != null ? Arrays.copyOf((Object[]) answer, idx + 1) : Array.newInstance(Object.class, idx + 1); + } + + Object result = Array.get(answer, idx); + if (result == null) { + result = context.getInjector().newInstance(type.getComponentType()); + Array.set(answer, idx, result); + } + + if (idx >= size) { + // replace array + if (configurer != null) { + configurer.configure(context, target, key, answer, true); + } else { + // fallback to reflection + boolean hit; + try { + hit = IntrospectionSupport.setProperty(context.getTypeConverter(), target, key, answer); + } catch (Exception e) { + throw new IllegalArgumentException("Cannot set property: " + key + " as an array because target bean has no setter method for the array"); + } + if (!hit) { + throw new IllegalArgumentException("Cannot set property: " + key + " as an array because target bean has no setter method for the array"); + } + } + } + + answer = result; } return answer != null ? answer : defaultValue; @@ -1035,7 +1090,7 @@ public final class PropertyBindingSupport { continue; } // must be a public static method that returns something - if (!Modifier.isStatic(method.getModifiers()) + if (!Modifier.isStatic(method.getModifiers()) || !Modifier.isPublic(method.getModifiers()) || method.getReturnType() == Void.TYPE) { continue; diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyConfigurerHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyConfigurerHelper.java new file mode 100644 index 0000000..df104d5 --- /dev/null +++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyConfigurerHelper.java @@ -0,0 +1,70 @@ +/* + * 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 org.apache.camel.CamelContext; +import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.ObjectHelper; + +/** + * Helper class for dealing with configurers. + * + * @see org.apache.camel.spi.PropertyConfigurer + * @see org.apache.camel.spi.PropertyConfigurerGetter + */ +public final class PropertyConfigurerHelper { + + private PropertyConfigurerHelper() { + } + + /** + * Resolves the given configurer. + * + * @param context the camel context + * @param target the target object for which we need a {@link org.apache.camel.spi.PropertyConfigurer} + * @return the resolved configurer, or <tt>null</tt> if no configurer could be found + */ + public static GeneratedPropertyConfigurer resolvePropertyConfigurer(CamelContext context, Object target) { + ObjectHelper.notNull(target, "target"); + ObjectHelper.notNull(context, "context"); + + return context.adapt(ExtendedCamelContext.class) + .getConfigurerResolver() + .resolvePropertyConfigurer(target.getClass().getSimpleName(), context); + } + + /** + * Resolves the given configurer. + * + * @param context the camel context + * @param target the target object for which we need a {@link org.apache.camel.spi.PropertyConfigurer} + * @param type the specific type of {@link org.apache.camel.spi.PropertyConfigurer} + * @return the resolved configurer, or <tt>null</tt> if no configurer could be found + */ + public static <T> T resolvePropertyConfigurer(CamelContext context, Object target, Class<T> type) { + ObjectHelper.notNull(target, "target"); + ObjectHelper.notNull(context, "context"); + + GeneratedPropertyConfigurer configurer = resolvePropertyConfigurer(context, target); + if (type.isInstance(configurer)) { + return type.cast(configurer); + } + + return null; + } +}