This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch bean in repository https://gitbox.apache.org/repos/asf/camel.git
commit dc84e3d5eb760ad5ea29c19ef8005d217692a007 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Apr 25 06:41:26 2019 +0200 CAMEL-13449: camel3 - Move bean component out of camel-core --- .../bean/BeanAnnotationExpressionFactory.java | 9 ++- .../apache/camel/language/bean/BeanExpression.java | 56 ++++++++++++--- .../apache/camel/language/bean/BeanLanguage.java | 84 ++++++++++++---------- .../camel/model/language/MethodCallExpression.java | 53 ++++++++------ .../issues/FilterBeanLanguageNonRegistryTest.java | 3 +- .../file/FileConsumerMoveExpressionTest.java | 3 +- .../java/org/apache/camel/language/BeanTest.java | 26 +++---- 7 files changed, 149 insertions(+), 85 deletions(-) diff --git a/core/camel-core/src/main/java/org/apache/camel/component/bean/BeanAnnotationExpressionFactory.java b/core/camel-core/src/main/java/org/apache/camel/component/bean/BeanAnnotationExpressionFactory.java index c825307..cbc935a 100644 --- a/core/camel-core/src/main/java/org/apache/camel/component/bean/BeanAnnotationExpressionFactory.java +++ b/core/camel-core/src/main/java/org/apache/camel/component/bean/BeanAnnotationExpressionFactory.java @@ -21,7 +21,7 @@ import java.lang.reflect.Method; import org.apache.camel.CamelContext; import org.apache.camel.Expression; -import org.apache.camel.language.bean.BeanLanguage; +import org.apache.camel.spi.Language; import org.apache.camel.support.ObjectHelper; import org.apache.camel.support.language.DefaultAnnotationExpressionFactory; import org.apache.camel.support.language.LanguageAnnotation; @@ -42,7 +42,12 @@ public class BeanAnnotationExpressionFactory extends DefaultAnnotationExpression method = null; } - return BeanLanguage.bean(beanName, method); + Language lan = camelContext.resolveLanguage("bean"); + if (method != null) { + return lan.createExpression(beanName + "?method=" + method); + } else { + return lan.createExpression(beanName); + } } protected String getFromAnnotation(Annotation annotation, String attribute) { diff --git a/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java b/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java index ef10407..c38c3f2 100644 --- a/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java +++ b/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanExpression.java @@ -42,16 +42,17 @@ import org.apache.camel.util.KeyValueHolder; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.OgnlHelper; import org.apache.camel.util.StringHelper; + import static org.apache.camel.util.ObjectHelper.hasDefaultPublicNoArgConstructor; /** * Evaluates an expression using a bean method invocation */ public class BeanExpression implements Expression, Predicate, AfterPropertiesConfigured { - private final Object bean; - private final String beanName; - private final Class<?> type; - private final String method; + private Object bean; + private String beanName; + private Class<?> type; + private String method; private volatile BeanHolder beanHolder; public BeanExpression(Object bean, String method) { @@ -75,6 +76,38 @@ public class BeanExpression implements Expression, Predicate, AfterPropertiesCon this.beanName = null; } + public Object getBean() { + return bean; + } + + public void setBean(Object bean) { + this.bean = bean; + } + + public String getBeanName() { + return beanName; + } + + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + public Class<?> getType() { + return type; + } + + public void setType(Class<?> type) { + this.type = type; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + @Override public String toString() { StringBuilder sb = new StringBuilder("BeanExpression["); @@ -100,6 +133,9 @@ public class BeanExpression implements Expression, Predicate, AfterPropertiesCon } // invoking the bean can either be the easy way or using OGNL + if (bean != null || type != null) { + validateHasMethod(exchange.getContext(), bean, type, method); + } // validate OGNL if (OgnlHelper.isInvalidValidOgnlExpression(method)) { @@ -147,11 +183,17 @@ public class BeanExpression implements Expression, Predicate, AfterPropertiesCon @Override public void afterPropertiesConfigured(CamelContext camelContext) { + // lets see if we can do additional validation that the bean has valid method during creation of the expression Object target = bean; if (bean == null && type == null && beanName != null) { target = CamelContextHelper.mandatoryLookup(camelContext, beanName); } validateHasMethod(camelContext, target, type, method); + + // if the bean holder doesn't exist then create it + if (beanHolder == null) { + beanHolder = createBeanHolder(camelContext); + } } /** @@ -203,11 +245,7 @@ public class BeanExpression implements Expression, Predicate, AfterPropertiesCon } } - /** - * Optimize to create the bean holder once, so we can reuse it for further - * evaluation, which is faster. - */ - private synchronized BeanHolder createBeanHolder(CamelContext context) { + private BeanHolder createBeanHolder(CamelContext context) { // either use registry lookup or a constant bean BeanHolder holder; if (bean != null) { diff --git a/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java b/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java index 24ea1c3..10f7cc0 100644 --- a/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java +++ b/core/camel-core/src/main/java/org/apache/camel/language/bean/BeanLanguage.java @@ -17,11 +17,9 @@ package org.apache.camel.language.bean; import org.apache.camel.Expression; -import org.apache.camel.IsSingleton; import org.apache.camel.Predicate; -import org.apache.camel.spi.Language; import org.apache.camel.support.ExpressionToPredicateAdapter; -import org.apache.camel.support.ObjectHelper; +import org.apache.camel.support.LanguageSupport; import org.apache.camel.util.StringHelper; /** @@ -38,41 +36,46 @@ import org.apache.camel.util.StringHelper; * its classname or the bean itself. */ @org.apache.camel.spi.annotations.Language("bean") -public class BeanLanguage implements Language, IsSingleton { - - /** - * Creates the expression based on the string syntax. - * - * @param expression the string syntax <tt>beanRef.methodName</tt> where methodName can be omitted - * @return the expression - */ - public static Expression bean(String expression) { - BeanLanguage language = new BeanLanguage(); - return language.createExpression(expression); +public class BeanLanguage extends LanguageSupport { + + private Object bean; + private Class<?> beanType; + private String ref; + private String method; + + public BeanLanguage() { + } + + public Object getBean() { + return bean; + } + + public void setBean(Object bean) { + this.bean = bean; + } + + public Class<?> getBeanType() { + return beanType; } - /** - * Creates the expression for invoking the bean type. - * - * @param beanType the bean type to invoke - * @param method optional name of method to invoke for instance to avoid ambiguity - * @return the expression - */ - public static Expression bean(Class<?> beanType, String method) { - Object bean = ObjectHelper.newInstance(beanType); - return bean(bean, method); + public void setBeanType(Class<?> beanType) { + this.beanType = beanType; } - /** - * Creates the expression for invoking the bean type. - * - * @param bean the bean to invoke - * @param method optional name of method to invoke for instance to avoid ambiguity - * @return the expression - */ - public static Expression bean(Object bean, String method) { - BeanLanguage language = new BeanLanguage(); - return language.createExpression(bean, method); + public String getRef() { + return ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; } public Predicate createPredicate(String expression) { @@ -80,7 +83,14 @@ public class BeanLanguage implements Language, IsSingleton { } public Expression createExpression(String expression) { - org.apache.camel.util.ObjectHelper.notNull(expression, "expression"); + // favour using the configured options + if (bean != null) { + return new BeanExpression(bean, method); + } else if (beanType != null) { + return new BeanExpression(beanType, method); + } else if (ref != null) { + return new BeanExpression(ref, method); + } String beanName = expression; String method = null; @@ -95,7 +105,7 @@ public class BeanLanguage implements Language, IsSingleton { int doubleColonIndex = expression.indexOf("::"); //need to check that not inside params int beginOfParameterDeclaration = expression.indexOf("("); - if (doubleColonIndex > 0 && (expression.indexOf("(") < 0 || doubleColonIndex < beginOfParameterDeclaration)) { + if (doubleColonIndex > 0 && (!expression.contains("(") || doubleColonIndex < beginOfParameterDeclaration)) { beanName = expression.substring(0, doubleColonIndex); method = expression.substring(doubleColonIndex + 2); } else { @@ -121,6 +131,6 @@ public class BeanLanguage implements Language, IsSingleton { } public boolean isSingleton() { - return true; + return false; } } diff --git a/core/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java b/core/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java index ddeb744..68520ba 100644 --- a/core/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java +++ b/core/camel-core/src/main/java/org/apache/camel/model/language/MethodCallExpression.java @@ -22,11 +22,12 @@ import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; +import org.apache.camel.AfterPropertiesConfigured; import org.apache.camel.CamelContext; import org.apache.camel.Expression; import org.apache.camel.Predicate; import org.apache.camel.RuntimeCamelException; -import org.apache.camel.language.bean.BeanExpression; +import org.apache.camel.spi.Language; import org.apache.camel.spi.Metadata; import org.apache.camel.util.ObjectHelper; @@ -56,14 +57,14 @@ public class MethodCallExpression extends ExpressionDefinition { } public MethodCallExpression(String beanName, String method) { - super((String)null); // use ref attribute to refer to the bean, and not @XmlValue + super((String)null); // we dont use @XmlValue but the attributes instead if (beanName != null && beanName.startsWith("ref:")) { beanName = beanName.substring(4); } else if (beanName != null && beanName.startsWith("bean:")) { beanName = beanName.substring(5); } - this.ref = beanName; - this.method = method; + setRef(beanName); + setMethod(method); } public MethodCallExpression(Object instance) { @@ -71,7 +72,7 @@ public class MethodCallExpression extends ExpressionDefinition { } public MethodCallExpression(Object instance, String method) { - super(ObjectHelper.className(instance)); // need to set some value in @XmlValue when we already have an instance bean + super((String)null); // we dont use @XmlValue but the attributes instead // must use setter as they have special logic setInstance(instance); setMethod(method); @@ -82,10 +83,10 @@ public class MethodCallExpression extends ExpressionDefinition { } public MethodCallExpression(Class<?> type, String method) { - super((String)null); // use beanType attribute to refer to the bean, and not @XmlValue - this.beanType = type; - this.beanTypeName = type.getName(); - this.method = method; + super((String)null); // we dont use @XmlValue but the attributes instead + setBeanType(type); + setBeanTypeName(type.getName()); + setMethod(method); } public String getLanguage() { @@ -151,8 +152,6 @@ public class MethodCallExpression extends ExpressionDefinition { @Override public Expression createExpression(CamelContext camelContext) { - Expression answer; - if (beanType == null && beanTypeName != null) { try { beanType = camelContext.getClassResolver().resolveMandatoryClass(beanTypeName); @@ -161,20 +160,30 @@ public class MethodCallExpression extends ExpressionDefinition { } } - // TODO: Must use setProperty, so we need to have properties for these on BeanExpression + // special for bean language where we need to configure it first + Language lan = camelContext.resolveLanguage("bean"); + configureLanguage(camelContext, lan); + // .. and create expression with null value as we use the configured properties instead + Expression exp = lan.createExpression(null); + if (exp instanceof AfterPropertiesConfigured) { + ((AfterPropertiesConfigured) exp).afterPropertiesConfigured(camelContext); + } + return exp; + } + protected void configureLanguage(CamelContext camelContext, Language language) { if (instance != null) { - answer = new BeanExpression(instance, method); - } else if (beanType != null) { - answer = new BeanExpression(beanType, method); - } else if (ref != null) { - answer = new BeanExpression(ref, method); - } else { - answer = new BeanExpression(getExpression(), method); + setProperty(language, "bean", instance); + } + if (beanType != null) { + setProperty(language, "beanType", beanType); + } + if (ref != null) { + setProperty(language, "ref", ref); + } + if (method != null) { + setProperty(language, "method", method); } - - configureExpression(camelContext, answer); - return answer; } @Override diff --git a/core/camel-core/src/test/java/org/apache/camel/component/bean/issues/FilterBeanLanguageNonRegistryTest.java b/core/camel-core/src/test/java/org/apache/camel/component/bean/issues/FilterBeanLanguageNonRegistryTest.java index 6046ba04..ca5e0f0 100644 --- a/core/camel-core/src/test/java/org/apache/camel/component/bean/issues/FilterBeanLanguageNonRegistryTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/component/bean/issues/FilterBeanLanguageNonRegistryTest.java @@ -18,7 +18,6 @@ package org.apache.camel.component.bean.issues; import org.apache.camel.ContextTestSupport; import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.language.bean.BeanLanguage; import org.junit.Test; public class FilterBeanLanguageNonRegistryTest extends ContextTestSupport { @@ -42,7 +41,7 @@ public class FilterBeanLanguageNonRegistryTest extends ContextTestSupport { MyBean myBean = new MyBean(); from("direct:start") - .filter().expression(BeanLanguage.bean(myBean, "isGoldCustomer")) + .filter(method(myBean, "isGoldCustomer")) .to("mock:result"); } }; diff --git a/core/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerMoveExpressionTest.java b/core/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerMoveExpressionTest.java index a591cc0..5fed08e 100644 --- a/core/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerMoveExpressionTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerMoveExpressionTest.java @@ -22,6 +22,7 @@ import org.apache.camel.Exchange; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.language.bean.BeanExpression; import org.apache.camel.language.bean.BeanLanguage; import org.junit.Before; import org.junit.Test; @@ -146,7 +147,7 @@ public class FileConsumerMoveExpressionTest extends ContextTestSupport { endpoint.setCamelContext(context); endpoint.setFile(new File("target/data/filelanguage/")); endpoint.setAutoCreate(false); - endpoint.setMove(BeanLanguage.bean("myguidgenerator")); + endpoint.setMove(new BeanExpression("myguidgenerator", null)); endpoint.setExclude(".*bak"); endpoint.setInitialDelay(10); diff --git a/core/camel-core/src/test/java/org/apache/camel/language/BeanTest.java b/core/camel-core/src/test/java/org/apache/camel/language/BeanTest.java index deaefdd..f87e0bf 100644 --- a/core/camel-core/src/test/java/org/apache/camel/language/BeanTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/language/BeanTest.java @@ -24,7 +24,7 @@ import org.apache.camel.Header; import org.apache.camel.LanguageTestSupport; import org.apache.camel.Message; import org.apache.camel.component.bean.MethodNotFoundException; -import org.apache.camel.language.bean.BeanLanguage; +import org.apache.camel.language.bean.BeanExpression; import org.junit.Test; public class BeanTest extends LanguageTestSupport { @@ -57,7 +57,7 @@ public class BeanTest extends LanguageTestSupport { @Test public void testBeanTypeExpression() throws Exception { - Expression exp = BeanLanguage.bean(MyUser.class, null); + Expression exp = new BeanExpression(MyUser.class, null); Exchange exchange = createExchangeWithBody("Claus"); Object result = exp.evaluate(exchange, Object.class); @@ -66,7 +66,7 @@ public class BeanTest extends LanguageTestSupport { @Test public void testBeanTypeAndMethodExpression() throws Exception { - Expression exp = BeanLanguage.bean(MyUser.class, "hello"); + Expression exp = new BeanExpression(MyUser.class, "hello"); Exchange exchange = createExchangeWithBody("Claus"); Object result = exp.evaluate(exchange, Object.class); @@ -76,7 +76,7 @@ public class BeanTest extends LanguageTestSupport { @Test public void testBeanInstanceAndMethodExpression() throws Exception { MyUser user = new MyUser(); - Expression exp = BeanLanguage.bean(user, "hello"); + Expression exp = new BeanExpression(user, "hello"); Exchange exchange = createExchangeWithBody("Claus"); Object result = exp.evaluate(exchange, Object.class); @@ -86,20 +86,22 @@ public class BeanTest extends LanguageTestSupport { @Test public void testNoMethod() throws Exception { MyUser user = new MyUser(); - Expression exp = BeanLanguage.bean(user, "unknown"); + Expression exp = new BeanExpression(user, "unknown"); Exchange exchange = createExchangeWithBody("Claus"); - Object result = exp.evaluate(exchange, Object.class); - assertNull(result); - assertNotNull(exchange.getException()); - MethodNotFoundException e = assertIsInstanceOf(MethodNotFoundException.class, exchange.getException()); - assertSame(user, e.getBean()); - assertEquals("unknown", e.getMethodName()); + try { + exp.evaluate(exchange, Object.class); + fail("Should throw exception"); + } catch (Exception e) { + MethodNotFoundException mnfe = assertIsInstanceOf(MethodNotFoundException.class, e.getCause()); + assertSame(user, mnfe.getBean()); + assertEquals("unknown", mnfe.getMethodName()); + } } @Test public void testNoMethodBeanLookup() throws Exception { - Expression exp = BeanLanguage.bean("foo.cake"); + Expression exp = new BeanExpression("foo", "cake"); Exchange exchange = createExchangeWithBody("Claus"); Object result = exp.evaluate(exchange, Object.class);